package labox.innovation.gameserver.model.actor.stat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import labox.innovation.gameserver.datatables.Experience;
import labox.innovation.gameserver.model.actor.L2Playable;
import labox.innovation.gameserver.model.actor.instance.L2PetInstance;

/**
 * 可操作的对象的状态集
 * 
 * @author Administrator
 * 
 */
public class PlayableStat extends CharStat {

	protected static final Logger _log = LoggerFactory.getLogger(PlayableStat.class.getName());

	/**
	 * 玩家分配的力量点
	 */
	private int _assignedSTR;

	/**
	 * 玩家分配的敏捷点
	 */
	private int _assignedDEX;

	/**
	 * 玩家分配的智力点
	 */
	private int _assignedINT;

	/**
	 * 玩家分配的精神点
	 */
	private int _assignedMEN;

	/**
	 * 玩家分配的体质点
	 */
	private int _assignedCON;

	/**
	 * 玩家未分配的属性点
	 */
	private int _unassigned;

	public PlayableStat(L2Playable activeChar) {
		super(activeChar);
	}

	/**
	 * 获得角色的基础力量
	 * 
	 * @return
	 */
	@Override
	public final int getBaseSTR() {
		return _assignedSTR + _activeChar.getTemplate().baseSTR;
	}

	/**
	 * 获得角色的基础敏捷值
	 * 
	 * @return
	 */
	@Override
	public final int getBaseDEX() {
		return _assignedDEX + _activeChar.getTemplate().baseDEX;
	}

	/**
	 * 获取角色的基础智力值
	 * 
	 * @return
	 */
	@Override
	public final int getBaseINT() {
		return _assignedINT + _activeChar.getTemplate().baseINT;
	}

	/**
	 * 获得角色的基础精神值
	 * 
	 * @return
	 */
	@Override
	public final int getBaseMEN() {
		return _assignedMEN + _activeChar.getTemplate().baseMEN;
	}

	/**
	 * 获得角色的基础体质
	 * 
	 * @return
	 */
	@Override
	public final int getBaseCON() {
		return _assignedCON + _activeChar.getTemplate().baseCON;
	}

	/**
	 * 设置角色的基础力量
	 * 
	 * @return
	 */
	public final void setAssignedSTR(int str) {
		_assignedSTR = str;
	}

	public final int getAssignedSTR() {
		return _assignedSTR;
	}

	/**
	 * 设置角色的基础敏捷值
	 * 
	 * @return
	 */
	public final void setAssignedDEX(int dex) {
		_assignedDEX = dex;
	}

	public final int getAssignedDEX() {
		return _assignedDEX;
	}

	/**
	 * 设置角色的基础智力值
	 * 
	 * @return
	 */
	public final void setAssignedINT(int INT) {
		_assignedINT = INT;
	}

	public final int getAssignedINT() {
		return _assignedINT;
	}

	/**
	 * 设置角色的基础精神值
	 * 
	 * @return
	 */
	public final void setAssignedMEN(int men) {
		_assignedMEN = men;
	}

	public final int getAssignedMEN() {
		return _assignedMEN;
	}

	/**
	 * 设置角色的基础体质
	 * 
	 * @return
	 */
	public final void setAssignedCON(int con) {
		_assignedCON = con;
	}

	public final int getAssignedCON() {
		return _assignedCON;
	}

	/**
	 * 设置未分配的属性点
	 * 
	 * @param point
	 */
	public final void setUnassignedPoint(int point) {
		_unassigned = point;
	}

	/**
	 * 获取未分配的属性点
	 * 
	 * @param point
	 */
	public final int getUnassignedPoint() {
		return _unassigned;
	}

	public boolean addExp(int addExp) {
		return addExp(addExp, true);
	}

	public void refreshPoint() {
		int old = _unassigned;
		_unassigned += _assignedSTR + _assignedDEX + _assignedINT + _assignedMEN + _assignedCON;
		_assignedSTR = 0;
		_assignedDEX = 0;
		_assignedINT = 0;
		_assignedMEN = 0;
		_assignedCON = 0;
		_log.info("洗点:未洗点前可分配点数:" + old + "洗点后可分配点数:" + _unassigned, _activeChar.getObjectId(), _activeChar.getName());
	}

	/**
	 * 增加经验，并判断是否可以增加等级
	 * 
	 * @param value
	 *            加成的经验值
	 * @return 是否增加成功
	 */
	public boolean addExp(int value, boolean fullcheckLevelUp) {
		if (!addBaseExp(value))
			return false;
		checkLevelUp(fullcheckLevelUp, false);
		return true;
	}

	public void checkLevelUp(boolean fullcheckLevelUp, boolean sendInfo) {
		if (_level + 1 <= Experience.MAX_LEVEL) {
			int expFL = getExpForLevel(_level + 1);
			if (_exp >= expFL) {
				if (fullcheckLevelUp) {
					int level;
					int exp = _exp;

					for (level = _level + 1; level <= Experience.MAX_LEVEL; ++level) {
						int expL = getExpForLevel(level);
						if (exp < expL) {
							--level;
							break;
						}
						exp -= expL;
					}
					if (level > Experience.MAX_LEVEL)
						level = Experience.MAX_LEVEL;

					if (level != _level) {
						addBaseExp(exp - _exp);
						addLevel(level - _level, sendInfo);//加若干级
					}
				} else {
					addBaseExp(-expFL);
					addLevel(1, sendInfo);
				}
			}
		}

	}

	protected boolean addBaseExp(int value) {
		if (_exp + value < 0)//如果当前增加后为负值
			return false;

		//		if (_exp + value > getExpForLevel(Experience.MAX_LEVEL))
		//			value = getExpForLevel(Experience.MAX_LEVEL) - _exp;//修正在达到最大值时的临界情况

		setExp(_exp + value);
		return true;
	}

	/**
	 * 减少经验，并判断是否可以降低等级
	 * 
	 * @param value
	 *            减少的经验值
	 * @return 是否减少成功
	 */
	public boolean removeExp(int value) {
		if (_exp - value < 0)
			value = _exp - 1;//至少让经验成1

		setExp(_exp - value);

		byte minimumLevel = 1;
		if (getActiveChar() instanceof L2PetInstance) {//如果是宠物的话
			// get minimum level from L2NpcTemplate
			minimumLevel = ((L2PetInstance) getActiveChar()).getTemplate().level;
		}
		byte level = minimumLevel;

		for (byte tmp = level; tmp <= Experience.MAX_LEVEL; tmp++) {
			if (_exp >= getExpForLevel(tmp))
				continue;
			level = --tmp;
			break;
		}
		if (level != _level && level >= minimumLevel)
			addLevel(level - _level, false);//降若干级
		return true;
	}

	public boolean addLevel(int value, boolean sendInfo) {
		if (_level + value > Experience.MAX_LEVEL) {//判断越界和临界情况
			value = Experience.MAX_LEVEL - _level;
		}
		boolean levelIncreased = _level + value > _level;
		value += _level;
		setLevel(value);
		//如果现在的经验大于下一级的经验或小于目前级别的经验，则重置到当前等级的经验
		//		if (_exp >= getExpForLevel(_level + 1) || getExpForLevel(_level) > _exp)
		//			setExp(getExpForLevel(_level));
		if (!levelIncreased)
			return false;
		getActiveChar().getStatus().setCurrentHpMp(getActiveChar().getStat().getMaxHp(), getActiveChar().getStat().getMaxMp());
		return true;
	}

	public int getExpForLevel(int level) {
		return level;
	}

	@Override
	public L2Playable getActiveChar() {
		return (L2Playable) _activeChar;
	}
}
